package com.interviewbackend.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.interviewbackend.client.ImageAnalysisClient;
import com.interviewbackend.dto.MultimodalDataRequestDTO;
import com.interviewbackend.entity.InterviewRecord;
import com.interviewbackend.entity.InterviewSession;
import com.interviewbackend.mapper.InterviewRecordMapper;
import com.interviewbackend.mapper.InterviewSessionMapper;
import com.interviewbackend.service.EvaluationService;
import com.interviewbackend.service.MultimodalAnalysisService;
import com.interviewbackend.util.SpeechSynthesisUtil;
import com.alibaba.fastjson.JSONObject;
import com.interviewbackend.util.TagUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;

@Service
public class MultimodalAnalysisServiceImpl implements MultimodalAnalysisService {

    private final ImageAnalysisClient imageAnalysisClient;
    private final InterviewSessionMapper interviewSessionMapper;
    private final InterviewRecordMapper interviewRecordMapper;
    private final EvaluationService evaluationService;
    private final InterviewFlowServiceImpl interviewFlowService;
    private final SpeechSynthesisUtil speechSynthesizerUtil;
    private RedisTemplate<String, Object> redisTemplate;

    private final Map<String, List<String>> sessionAnalysisResults = new ConcurrentHashMap<>();

    private final Map<String, List<CompletableFuture<Void>>> sessionFutures = new ConcurrentHashMap<>();

    @Autowired
    public MultimodalAnalysisServiceImpl(ImageAnalysisClient imageAnalysisClient,
                                         InterviewSessionMapper interviewSessionMapper,
                                         InterviewRecordMapper interviewRecordMapper,
                                         EvaluationService evaluationService,
                                         InterviewFlowServiceImpl interviewFlowService,
                                         SpeechSynthesisUtil speechSynthesizerUtil,
                                         RedisTemplate<String, Object> redisTemplate) {
        this.imageAnalysisClient = imageAnalysisClient;
        this.interviewSessionMapper = interviewSessionMapper;
        this.interviewRecordMapper = interviewRecordMapper;
        this.evaluationService = evaluationService;
        this.interviewFlowService = interviewFlowService;
        this.speechSynthesizerUtil = speechSynthesizerUtil;
        this.redisTemplate = redisTemplate;
    }

    @Override
    public void analyzeAndStore(MultimodalDataRequestDTO request) {
        String sessionId = request.getSessionId();

        CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
            List<String> imageUrls = request.getImageUrls();
            String text = request.getText();

            // 统一图文分析
            String result = imageAnalysisClient.analyzeImageAndText(imageUrls, text);

            sessionAnalysisResults
                    .computeIfAbsent(sessionId, k -> new ArrayList<>())
                    .add(result);
        });

        trackAnalyzeFuture(sessionId, future);
    }

    @Override
    public void trackAnalyzeFuture(String sessionId, CompletableFuture<Void> future) {
        sessionFutures.computeIfAbsent(sessionId, k -> Collections.synchronizedList(new ArrayList<>())).add(future);
    }

    @Override
    public void waitForAllAnalysisCompleted(String sessionId) {
        List<CompletableFuture<Void>> futures = sessionFutures.getOrDefault(sessionId, Collections.emptyList());
        try {
            CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sessionFutures.remove(sessionId); // 清理
        }
    }

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    private void writeResultToRedis(String sessionId, String resultJson) {
        String key = "interview:result:" + sessionId;
        stringRedisTemplate.opsForValue().set(key, resultJson, 10, TimeUnit.MINUTES);
    }

    @Override
    public void finalizeAnalysis(String sessionId, String answerText) {
        try {
            // 等待分析任务完成
            waitForAllAnalysisCompleted(sessionId);

            List<String> analysisResults = sessionAnalysisResults.get(sessionId);

            if (analysisResults == null || answerText == null) {
                writeResultToRedis(sessionId, "{\"status\":\"error\",\"message\":\"未找到对应的会话数据\"}");
                return;
            }

            InterviewSession session = interviewSessionMapper.selectById(sessionId);

            InterviewRecord interviewRecord = interviewRecordMapper.selectOne(
                    new QueryWrapper<InterviewRecord>()
                            .eq("interview_id", session.getId())
                            .eq("round_index", session.getRoundIndex())
                            .eq("question_index", session.getCurrentQuestionIndex())
            );

            if (interviewRecord == null) {
                writeResultToRedis(sessionId, "{\"status\":\"error\",\"message\":\"未找到匹配的面试记录\"}");
                return;
            }

            String finalAnalysis = "图像和语音联合分析结果：\n" + String.join("\n", analysisResults);

            interviewRecord.setEvaluationJson(finalAnalysis);
            interviewRecord.setAnswerText(answerText);

            // 清理缓存
            sessionAnalysisResults.remove(sessionId);

            String evaluationResult = evaluationService.evaluateInterview(interviewRecord);
            interviewRecord.setSuggestion(evaluationResult);
            interviewRecordMapper.updateById(interviewRecord);

            boolean isAlreadyFollowUp = Boolean.TRUE.equals(interviewRecord.getIsFollowUp());
            boolean needFollowUp = !isAlreadyFollowUp &&
                    (evaluationResult.contains("追问") || evaluationResult.contains("不充分"));

            session.setNeedFollowUp(needFollowUp);
            session.setCurrentQuestionIndex(session.getCurrentQuestionIndex() + 1);
            interviewSessionMapper.updateById(session);

            String nextQuestion = interviewFlowService.generateNextQuestion(session.getId());
            String style = (String) redisTemplate.opsForValue().get("interview:style:" + sessionId);
            String audioBase64 = speechSynthesizerUtil.synthesizeToBase64(nextQuestion, style);

            JSONObject json = new JSONObject();
            json.put("status", "done");
            json.put("questionText", nextQuestion);
            json.put("audioBase64", audioBase64);
            json.put("roundIndex", TagUtil.intToTag(session.getRoundIndex()));

            writeResultToRedis(sessionId, json.toJSONString());

        } catch (Exception e) {
            e.printStackTrace();
            writeResultToRedis(sessionId, "{\"status\":\"error\",\"message\":\"" + e.getMessage() + "\"}");
        }
    }

}
